Passed
Push — main ( 2f5713...1df88a )
by Andrii
02:07
created

ClassComponent   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 1
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 1
rs 10
c 0
b 0
f 0
wmc 1
1
import {
2
  Component,
3
  PureComponent
4
} from "react"
5
import type {
6
  ClassHash,
7
  ClassNamesProperty,
8
  ClassNames
9
} from "./defs"
10
11
type Props = ClassNames<true, ClassNamesProperty<{props: ClassHash}>>
12
function Functional(_: ClassNames<ClassNamesProperty<{functional: ClassHash}>>) { return null }
13
class ClassComponent extends Component<ClassNames<ClassNamesProperty<{component: ClassHash; comp0: ClassHash}>>> {}
14
class ClassPureComponent extends PureComponent<ClassNames<ClassNamesProperty<{pureComponent: ClassHash}>>> {}
15
16
describe("ClassNames", () => {
17
  describe("direct", () => {
18
    it("<true>", () => {
19
      const suites: Record<string, ClassNames<true>> = {
20
        "className only": {className: ""},
21
        //@ts-expect-error Property 'className' is missing
22
        "empty object"
23
        : {},
24
        "classnames only": {
25
          //@ts-expect-error Object literal may only specify known properties, but 'classnames' does not exist
26
          classnames: {}
27
        },
28
        "className and classnames": {
29
          className: "",
30
          //@ts-expect-error Object literal may only specify known properties, but 'classnames' does not exist
31
          classnames: {}
32
        }
33
      }
34
      expect(suites).toBeInstanceOf(Object)
35
    })
36
  
37
    it("<{class1, class2}>", () => {
38
      const suites: Record<string, ClassNames<{classnames: {class1: ClassHash; class2: ClassHash}}>> = {
39
        "omitted": {
40
          //@ts-expect-error ReactRelated
41
          classnames: {
42
            class1: undefined
43
          }
44
        },
45
        "classnames only": {
46
          classnames: {class1: undefined, class2: undefined}
47
        },
48
        "className only": {
49
          //@ts-expect-error Object literal may only specify known properties, but 'className' does not exist
50
          className: ""
51
        },
52
        //@ts-expect-error Property 'classnames' is missing
53
        "empty object"
54
        : {},
55
        "className and classnames": {
56
          //@ts-expect-error Object literal may only specify known properties, but 'className' does not exist
57
          className: "",
58
          classnames: {class1: undefined, class2: undefined}
59
        }
60
      }
61
      expect(suites).toBeInstanceOf(Object)
62
    })
63
  
64
    it("<true, {class1, class2}>", () => {
65
      const suites: Record<string, ClassNames<true, {classnames: {class1: ClassHash; class2: ClassHash}}>> = {
66
        "className and classnames": {
67
          className: "",
68
          classnames: {class1: undefined, class2: undefined}
69
        },
70
        //@ts-expect-error Property 'className' is missing
71
        "classnames only": {
72
          classnames: {class1: undefined, class2: undefined}
73
        },
74
        //@ts-expect-error Property 'classnames' is missing
75
        "className only": {
76
          className: ""
77
        }
78
      }
79
      expect(suites).toBeInstanceOf(Object)
80
    })
81
  
82
    it("nothing to pick", () => {
83
      type NoClassNames = ClassNames<true>
84
      const suite1: Record<string, ClassNames<
85
        //@ts-expect-error
86
        NoClassNames,
87
        {classnames: {class1: ClassHash}},
88
        {classnames: {class1: ClassHash}}
89
      >> = {
90
        "nothing": {classnames: {class1: ""}}
91
      }
92
      const suite2: Record<string, ClassNames<
93
        {classnames: {class1: ClassHash}},
94
        {classnames: {class1: ClassHash}},
95
        //@ts-expect-error
96
        NoClassNames
97
      >> = {
98
        "nothing": {classnames: {class1: ""}}
99
      }
100
      expect({suite1, suite2}).toBeInstanceOf(Object)
101
    })
102
  })
103
104
  describe("from", () => {
105
    it("manually merge", () => {
106
      type AppClassNames = (
107
        ClassNamesProperty<{App: ClassHash}>
108
        & ClassNames<typeof ClassComponent>
109
        & ClassNames<typeof ClassPureComponent>
110
        & ClassNames<typeof Functional>
111
        & ClassNames<Props>
112
      );
113
    
114
      const suites: Record<string, AppClassNames["classnames"]> = {
115
        "exact": {
116
          App: undefined,
117
          component: undefined,
118
          comp0: undefined,
119
          functional: undefined,
120
          props: undefined,
121
          pureComponent: undefined
122
        },
123
        "redundant": {
124
          //@ts-expect-error Object literal may only specify known properties, and 'redundant' does not exist
125
          redundant: undefined,
126
          App: undefined,
127
          component: undefined,
128
          functional: undefined,
129
          props: undefined,
130
          pureComponent: undefined,
131
        },
132
        //@ts-expect-error Property 'App' is missing
133
        "missed App": {
134
          component: undefined,
135
          functional: undefined,
136
          props: undefined,
137
          pureComponent: undefined,
138
        },
139
        //@ts-expect-error Property 'component' is missing
140
        "missed component": {
141
          App: undefined,
142
          functional: undefined,
143
          props: undefined,
144
          pureComponent: undefined,
145
        },
146
        //@ts-expect-error Property 'pureComponent' is missing
147
        "missed pureComponent": {
148
          App: undefined,
149
          component: undefined,
150
          functional: undefined,
151
          props: undefined,
152
        },
153
        //@ts-expect-error Property 'functional' is missing 
154
        "missed functional": {
155
          App: undefined,
156
          component: undefined,
157
          props: undefined,
158
          pureComponent: undefined,
159
        },
160
        //@ts-expect-error Property 'props' is missing
161
        "missed props": {
162
          App: undefined,
163
          component: undefined,
164
          functional: undefined,
165
          pureComponent: undefined,
166
        }
167
      }
168
      
169
      expect(suites).toBeInstanceOf(Object)
170
    })
171
  
172
    it("multiple apply", () => {
173
      type AppClassNames = ClassNames<
174
          true,
175
          ClassNamesProperty<{App: ClassHash}>,
176
          typeof ClassComponent,
177
          typeof ClassPureComponent,
178
          typeof Functional,
179
          Props
180
      >;
181
  
182
      const suites: Record<string, AppClassNames["classnames"]> = {
183
        "exact": {
184
          App: undefined,
185
          component: undefined,
186
          comp0: undefined,
187
          functional: undefined,
188
          props: undefined,
189
          pureComponent: undefined
190
        }
191
      }
192
  
193
      expect(suites).toBeInstanceOf(Object)
194
    })
195
  })    
196
})
197
198
describe("ClassNamesProperty", () => {
199
  it("Free declaration", () => {
200
    type Props = ClassNamesProperty<{
201
      class1: ClassHash, class2: ClassHash
202
    }>
203
    const suites: Record<string, Props["classnames"]> = {
204
      "all setted": {
205
        class1: "class1",
206
        class2: undefined
207
      },
208
      "redundant": {
209
        class1: "class1",
210
        class2: undefined,
211
        //@ts-expect-error
212
        redundant: "redundant"
213
      },
214
      //@ts-expect-error
215
      "missed": {
216
        class1: "class1"
217
      },
218
      "wrong type": {
219
        class1: "class1",
220
        //@ts-expect-error
221
        class2: false
222
      }
223
    }
224
    expect(suites).toBeInstanceOf(Object)
225
  })
226
  
227
  it("Module based", () => {
228
    type CssModule = {
229
      App: ClassHash
230
      class1: ClassHash, class2: ClassHash
231
    }
232
233
    type Props = ClassNamesProperty<CssModule, {
234
      class1: ClassHash
235
      class2: ClassHash
236
      //TODO #12 Why no suggestion? Means - no rename effect
237
    }>
238
239
    type PropsWithWrong = ClassNamesProperty<CssModule,
240
      //@ts-expect-error
241
      {
242
        class1: ClassHash
243
        class3: ClassHash
244
      }
245
    >
246
    
247
    const suite4wrong: PropsWithWrong["classnames"] = {
248
        //@ts-expect-error Object literal may only specify known properties, but 'class3' does not exist
249
        class3: undefined,
250
    },
251
    suite: Props["classnames"] = {
252
      class1: "class1",
253
      class2: undefined
254
    }
255
    expect({suite4wrong, suite}).toBeInstanceOf(Object)
256
  })
257
})
258